package cn.hhchat.wp.util;

import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAdjusters;
import java.time.temporal.WeekFields;
import java.util.Date;
import java.util.Locale;

/**
 * Created this one by HMH on 2017/10/22.
 */
public class DateUtil {
    public static Date getFirstDayOfWeekInDate(int year, int week) {
        return getDate(getFirstDayOfWeekInLocalDateTime(year,week));
    }

    public static Date getLastDayOfWeekInDate(int year, int week) {
        return getDate(getFirstDayOfWeekInLocalDateTime(year, week));
    }

    public static Date[] getBoundOfWeekInDate(Date date) {
        return getBoundOfWeekInDate(date.toInstant());
    }

    public static Date[] getBoundOfWeekInDate(Instant instant) {
        LocalDate localDate = getLocalDate(instant);
        return getBoundOfWeekInDate(localDate.getYear(), getWeekOfYear(localDate));
    }

    public static LocalDateTime getFirstDayOfWeekInLocalDateTime(int year, int week) {
        return getBoundOfWeekInLocalDateTime(year, week)[0];
    }

    public static LocalDateTime getLastDayOfWeekInLocalDateTime(int year, int week) {
        return getBoundOfWeekInLocalDateTime(year, week)[1].minusDays(1);
    }

    public static Date[] getBoundOfWeekInDate(int year, int week) {
        LocalDateTime[] localDateTimeBound = getBoundOfWeekInLocalDateTime(year, week);
//      get date object
        Date startDate = getDate(localDateTimeBound[0]);
        Date endDate = getDate(localDateTimeBound[1]);
        Date[] bound = new Date[2];

        bound[0] = startDate;
        bound[1] = endDate;

        return bound;
    }

    public static LocalDateTime[] getBoundOfWeekInLocalDateTime(int year, int week) {
//        convert to same year
        LocalDate sameYearDate = LocalDate.of(year, LocalDate.now().getMonth(), LocalDate.now().getDayOfMonth());
//        move to same week
        int curWeek = getWeekOfYear(sameYearDate);
        int diff = curWeek - week;
        sameYearDate = sameYearDate.minusWeeks(diff);
//        get day of first / next
        LocalDate firstDayOfWeek = sameYearDate.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY));
        LocalDate mondayOfNextWeek = firstDayOfWeek.with(TemporalAdjusters.next(DayOfWeek.MONDAY));
//        set to 00:00
        LocalDateTime start = firstDayOfWeek.atStartOfDay();
        LocalDateTime end = mondayOfNextWeek.atStartOfDay();
//        get date object
        LocalDateTime[] bound = new LocalDateTime[2];
        bound[0] = start;
        bound[1] = end;
        return bound;
    }

    public static int getWeekOfYear(LocalDate localDate) {
        //如果是周日，应该与上周一相同，其他不变
        return localDate.get(WeekFields.ISO.weekOfYear());
    }

    public static Date getDate(LocalDate localDate) {
        return getDate(localDate.atStartOfDay());
    }

    public static Date getDate(LocalDateTime localDateTime) {
        return Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
    }

    public static LocalDateTime getLocalDateTime(Date date) {
        return LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault());
    }

    public static LocalDate getLocalDate(Date date) {
        return getLocalDateTime(date).toLocalDate();
    }
    public static LocalDate getLocalDate(Instant instant) {
        return getLocalDateTime(new Date(instant.toEpochMilli())).toLocalDate();
    }

    private static DateTimeFormatter defaultDateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
    private static DateTimeFormatter defaultDateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");

    public static String formatDate(Date date) {
        return defaultDateFormatter.format(getLocalDateTime(date));
    }
    public static String formatDateTime(Date date){
        return defaultDateTimeFormatter.format(getLocalDateTime(date));
    }

}
